#include "EpQString.h"
#include <QDebug>
#include <iostream>
#include <QByteArray>
#include <QDateTime>

EpQString::EpQString(QObject *parent) : QObject(parent)
{
    qSetMessagePattern("[%{if-debug}DBUG%{endif}"
                       "%{if-info}\033[32mINFO%{endif}"
                       "%{if-warning}\033[33mWARN%{endif}"
                       "%{if-critical}\033[31mERRO%{endif}"
                       "%{if-fatal}\033[35mFATL%{endif}] "
                       "%{time h:mm:ss.zzz} "
                       "%{line}"
                       " %{message}\033[0m");

    qDebug()<<"初级用法示例-------------";
    epElementary();

    qDebug()<<"中级用法示例-------------";
    epIntermediate();

    qDebug()<<"高级用法示例-------------";
    epAdvanced();
}

void EpQString::epElementary()
{


    //1.增
    {
        QString strHello = "H";
        //追加字符串
        strHello += "ello"; //strHello == "Hello"
        qDebug()<<"strHello:"<<strHello;

        //追加字符串
        strHello.append(" 你好!"); //strHello == "Hello 你好!"
        qDebug()<<"strHello:"<<strHello;
    }


    //2.删
    {
        QString strHello = "Hello world!";

        //字符串删除0~6之间的字符
        strHello.remove(0,6); //strHello == "world!"
        qDebug()<<"remove:"<<strHello;

        //清空字符串
        strHello.clear(); //strHello == ""
        qDebug()<<"clear:"<<strHello;
    }

    //3.改
    {
        //直接赋值
        QString strText("hello");   //strText == "hello"
        qDebug()<<strText;

        strText = 'h';              //strText == "h"
        qDebug()<<strText;
    }

    {
        //字符串替换
        QString strHello = "Hello world!";
        strHello.replace("Hello ",""); //strHello == "world!"
        qDebug()<<"replace:"<<strHello;
    }

    {
        //中间插入字符串
        QString strHello = "H world!";
        strHello.insert(1,"ello"); //strHello == "Hello world!"
        qDebug()<<"insert:"<<strHello;
    }

    {
        //不同类型数据拼接字符串
        QString strText;

        strText = QString("温度: %1℃ PM2.5: %2μg/m³").arg(23.8).arg(12); //strText == "温度: 23.8℃ PM2.5: 12μg/m³"
        qDebug()<<strText;

        //单个arg最多可支持9个QString
        strText = QString("%1_%2.%3").arg("2022","0213","log"); //strText == "2022_0213.log"
        qDebug()<<strText;
    }

    //4.查
    {
        //字符串空判断
        bool bOk;
        QString strNull;
        QString strEmpty = "";
        QString strText = "abc";

        //判断字符串是否初始化
        bOk = strNull.isNull(); //return true
        qDebug()<<bOk;
        bOk = strEmpty.isNull(); //return false
        qDebug()<<bOk;
        bOk = strText.isNull(); //return false
        qDebug()<<bOk;

        //字符串是否为空
        bOk = strNull.isEmpty(); //return true
        qDebug()<<bOk;
        bOk = strEmpty.isEmpty(); //return true
        qDebug()<<bOk;
        bOk = strText.isEmpty(); //return false
        qDebug()<<bOk;
    }

    {
        //字符串比较
        QString strText = "data";
        if("data" == strText){ //true
            qDebug()<<true;
        }

        //区分大小写比对
        if(0 == strText.compare("data",Qt::CaseSensitive)){
            qDebug()<<"相同";
        }

        //不区分大小写比对
        if(0 == strText.compare("DATA",Qt::CaseInsensitive)){
            qDebug()<<"相同";
        }
    }
    {
        //字符串前缀、后缀判断
        QString strHello = "2022_12.txt";
        bool bYes;
        bYes = strHello.startsWith("2022"); //return true
        qDebug()<<"startsWith:"<<bYes;

        bYes = strHello.endsWith(".txt");   //return true
        qDebug()<<"endsWith:"<<bYes;

        //判断是否包含 不区分大小写方式
        bYes = strHello.contains(".txt",Qt::CaseInsensitive);   //return true
        qDebug()<<"contains:"<<bYes;
    }


    {
        //查找位置
        QString strHello = "aHello Hello!";
        int nIndex = -1;
        nIndex = strHello.indexOf("Hello"); //return 1
        qDebug()<<"nIndex:"<<nIndex;

        //从指定位置开始向后查找
        nIndex = strHello.indexOf("Hello",2);//return 7
        qDebug()<<"nIndex:"<<nIndex;

        nIndex = strHello.indexOf("Hello",9);//return -1
        qDebug()<<"nIndex:"<<nIndex;
    }


    {
        //计算字符串长度
        //纯英文
        QString strHello = "Hello";
        int nSize = 0;
        nSize = strHello.size(); //return 5
        qDebug()<<"nSize:"<<nSize;

        nSize = strHello.length();//return 5
        qDebug()<<"nSize:"<<nSize;

        nSize = strHello.count();//return 5
        qDebug()<<"nSize:"<<nSize;

        nSize = strlen(strHello.toUtf8().data());//return 5
        qDebug()<<"nSize:"<<nSize;

        //带中文的
        strHello = "你好123";
        nSize = strHello.size(); //return 5
        qDebug()<<"nSize:"<<nSize;

        nSize = strHello.length();//return 5
        qDebug()<<"nSize:"<<nSize;

        nSize = strHello.count();//return 5
        qDebug()<<"nSize:"<<nSize;

        nSize = strlen(strHello.toUtf8().data());//return 9
        qDebug()<<"nSize:"<<nSize;
    }

    //5.转换
    {
        //int<->QString
        int nNum = 255;
        QString strText;

        //整数转为十进制的字符串
        strText = QString::number(nNum); //return "255"
        qDebug()<<strText;

        //整数转为十六进制的字符串
        strText = QString::number(nNum,16).toUpper(); //return "FF"
        qDebug()<<strText;

        //字符串以十进制方式转为整数
        bool bOk;
        nNum = strText.setNum(88).toInt(&bOk,10); //return 88
        if(bOk){
            qDebug()<<"转换成功:"<<nNum;
        }
    }

    {
        //double<->QString
        double dNum = 12.53487;
        QString strText;

        //小数转为字符串，保留小数点后三位
        strText = QString::number(dNum,'f',3); //return "12.535"
        qDebug()<<strText;

        //小数转为字符串，保留小数点后三位 但是是科学计数方式显示
        strText = QString::number(dNum,'e',3); //return "1.253e+01"
        qDebug()<<strText;

        //小数转为字符串，保留三位数字显示
        strText = QString::number(dNum,'g',3); //return "12.5"
        qDebug()<<strText;
    }
}

void EpQString::epIntermediate()
{
    //1.转换
    {
        //与char*互转
        QString strHello = "Hello 你好!";

        char *string = strHello.toUtf8().data();
        qDebug()<<"QString 转char*:"<<string;

        QString qstring(string);
        qDebug()<<"char* 转 QString:"<<qstring;
    }

    {
        //与std::string 互转
        std::string stdtring = QString("stdstring").toStdString();
        qDebug()<<"QString 转 std::string:"<<stdtring.data();

        QString strFromStd = QString::fromStdString(stdtring);
        qDebug()<<"std::string 转 QString :"<<stdtring.data();
    }

    {
        //与十六进制字符串互转
        QString strHex = "ABFF12";

        QByteArray byteHex = QByteArray::fromHex(strHex.toUtf8());
        qDebug()<<"QString 转 hex:"<<byteHex;

        strHex = QString(byteHex.toHex(':'));
        qDebug()<<"hex 转 QString:"<<strHex;
    }



    {
        //与时间的互转

        //日期时间 转 QString
        QString strText = QDateTime(QDate(2022,1,1),QTime(12,59,12,123))
                .toString("yyyy-MM-dd HH:mm:ss.zzz"); //strText == "2022-01-01 12:59:12.123"
        qDebug()<<"dateTime:"<<strText;

        //QString 转 日期时间
        QDateTime dt = QDateTime::fromString(strText,"yyyy-MM-dd HH:mm:ss.zzz"); //dt == QDateTime(2022-01-01 12:59:12.123 中国标准时间 Qt::LocalTime)
        qDebug()<<"datetime:"<<dt;
    }
}

void EpQString::epAdvanced()
{
    //1.拼接
    {
        QString strText;

        //255以十六进制的字符串形式显示
        strText = QString("0x%1").arg(255,0,16); //strText == "0xff"
        qDebug()<<strText;


        //255以8位宽度显示 填充0
        strText = QString("%1").arg(255,8,10,QChar('0')); //strText == "00000255"
        qDebug()<<strText;


        //小数转为字符串
        double dDelta = 10.153962;
        //double重载的arg,后两个参数format、precision，一个指定转换格式，一个指定精度。格式默认为 'g' 或 'G'

        //对于'g'和'G'格式，精度表示有效数字的最大数目(后面的零被省略)
        strText = QString("delta:%1").arg(dDelta,0,'g',5); //strText == "delta:10.154"
        qDebug()<<strText;

        strText = QString("delta:%1").arg(dDelta,0,'G',5); //strText == "delta:10.154"
        qDebug()<<strText;

        //对于'e','E'和'f'格式，精度表示小数点后的位数
        strText = QString("delta:%1").arg(dDelta,0,'e',3); //strText == "delta:1.015e+01"
        qDebug()<<strText;

        strText = QString("delta:%1").arg(dDelta,0,'E',3); //strText == "delta:1.015e+01"
        qDebug()<<strText;

        //保留小数点后3位小数
        strText = QString("delta:%1").arg(dDelta,0,'f',3); //strText == "10.154"
        qDebug()<<strText;
    }

    //2.正则匹配
    {
        //@TODO
    }
}
